home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / OTCodeResource / OTGetDefaultEthernetAddress.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  5.9 KB  |  257 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        OTGetDefaultEthernetAddress.c
  3.  
  4.     Contains:    Demo of accessing OT from CodeWarrior 68K and
  5.                 Symantec for MPW 68K code resource.
  6.  
  7.     Written by: Quinn "The Eskimo!"
  8.  
  9.     Copyright:    © 1996-8 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13. */
  14.  
  15. #define qDebug 1
  16.  
  17. /////////////////////////////////////////////////////////////////////
  18. // Standard OT Interfaces
  19.  
  20. #include <OpenTransport.h>
  21. #include <OpenTptLinks.h>
  22.  
  23. /////////////////////////////////////////////////////////////////////
  24. // Low-Level OT Interfaces
  25.  
  26. #include <OTDebug.h>
  27.  
  28. // OTDebugStr is not defined in any OT header files, but it is
  29. // exported by the libraries, so we define the prototype here.
  30.  
  31. extern pascal void OTDebugStr(const char* str);
  32.  
  33. /////////////////////////////////////////////////////////////////////
  34. // Other Toolbox Interfaces
  35.  
  36. #include <HyperXCMD.h>
  37. #include <TextUtils.h>
  38. #include <Strings.h>
  39.  
  40. /////////////////////////////////////////////////////////////////////
  41. // Specical Envirnoment Dependent Stuff
  42.  
  43. #if defined(__MWERKS__)
  44.     #include <A4Stuff.h>
  45.  
  46.     extern UInt32 ZZZApplParamsHack[8];
  47.  
  48.     // Evil pseudo-LibraryManager stuff
  49.  
  50.     typedef long GlobalWorld;
  51.  
  52.     GlobalWorld GetCurrentGlobalWorld(void):__D0
  53.         = {0x200D};                                    /* move.l    A5,D0        */
  54.  
  55.     void SynchGlobalWorldFromA4(void)
  56.         = {0x2A4C};                                    /* move.l    A4,A5        */
  57.  
  58.     void SynchA4FromGlobalWorld(void)
  59.         = {0x284D};                                    /* move.l    A5,A4        */
  60.  
  61.     GlobalWorld SetCurrentGlobalWorld(GlobalWorld:__A0):__D0
  62.         = {0x200D,                                    /* move.l    A5,D0        */
  63.            0x2A48};                                    /* move.l    A0,A5        */
  64.  
  65. #else
  66.     #include <LibraryManagerUtilities.h>
  67.     #include <LibraryManager.h>
  68. #endif
  69.  
  70. /////////////////////////////////////////////////////////////////////
  71.  
  72. // Forward definition for TrueMain
  73.  
  74. static void TrueMain(XCmdPtr xpb);
  75.  
  76. /////////////////////////////////////////////////////////////////////
  77. // Standard XCMD main entry point, one for each environment.
  78.  
  79. #if defined(__MWERKS__)
  80.  
  81.     pascal void main(XCmdPtr xpb);
  82.  
  83.     pascal void main(XCmdPtr xpb)
  84.         // Metrowerks main line.
  85.     {
  86.         long oldA4;
  87.         GlobalWorld oldWorld;
  88.         UInt32 *junk;
  89.     
  90.         Debugger();
  91.         
  92.         // Create a reference to our dummy AppParams globals and
  93.         // assign it to a pointer.  This prevents the linker
  94.         // from dead-stripper the variable.
  95.         
  96.         junk = &ZZZApplParamsHack[1];
  97.         
  98.         // Now save A5, setup A4, and then setup A4 from A5.
  99.         
  100.         oldWorld = GetCurrentGlobalWorld();
  101.         
  102.         oldA4 = SetCurrentA4();
  103.         SynchGlobalWorldFromA4();
  104.     
  105.         // Call the real code.
  106.         
  107.         TrueMain(xpb);
  108.         
  109.         // Clean up.
  110.         
  111.         (void) SetCurrentGlobalWorld(oldWorld);
  112.         (void) SetA4(oldA4);
  113.     
  114.         // Debugger();
  115.     }
  116.     
  117. #else
  118.     
  119.     pascal void MAIN(XCmdPtr xpb)
  120.         // Symantec main line.
  121.     {
  122.         OSStatus err;
  123.         GlobalWorld oldWorld;
  124.     
  125.         Debugger();
  126.         
  127.         // Save A5 and then init our code resource's A5 world.
  128.         
  129.         oldWorld = GetCurrentGlobalWorld();
  130.         err = InitCodeResource();
  131.         if (err != noErr) {
  132.             // No point using a DebugStr because the string would A5 relative
  133.             //    and this failure indicates that A5 could not be setup!
  134.             Debugger();
  135.         } else {
  136.  
  137.             // Call the real code.
  138.  
  139.             TrueMain(xpb);
  140.             
  141.             // Clean up.
  142.             
  143.             (void) SetCurrentGlobalWorld(oldWorld);
  144.             FreeGlobalWorld();
  145.         }
  146.         // Debugger();
  147.     }
  148.     
  149. #endif
  150.  
  151. /////////////////////////////////////////////////////////////////////
  152. // Generic OT Stuff
  153.  
  154. struct EnetAddress {
  155.     unsigned char bytes[6];
  156. };
  157. typedef struct EnetAddress EnetAddress, *EnetAddressPtr;
  158.  
  159. typedef struct T8022Address T8022Address;
  160.  
  161. static T8022Address gSimpleAddr = {
  162.     AF_8022,                                // OTAddressType for 802 provider
  163.     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},    // hardware address, use zeros for bind requests
  164.     0x8888,                                    // SAP / protocol type, value > 1500 implies ethernet protocol with no SNAP
  165.     {0x00,0x00,0x00,0x00,0x00}
  166. };
  167.  
  168. static OSStatus GetDefaultEthernetAddress(EnetAddressPtr defEnetAddr)
  169.     // This routine returns the default Ethernet address of the machine
  170.     // in the (6 byte) buffer pointed to by defEnetAddr.
  171. {
  172.     OSStatus        err;
  173.     OSStatus        junk;
  174.     EndpointRef        ep;
  175.     TBind            bindRequest;
  176.     TBind            bindResult;
  177.     T8022Address    resultAddr;
  178.  
  179.  
  180.     ep = OTOpenEndpoint(OTCreateConfiguration(kEnetName), 0, 0, &err);
  181.     if (err == kOTNoError) {
  182.  
  183.         // Setup bind request
  184.  
  185.         OTMemzero(&bindRequest, sizeof(TBind));
  186.         bindRequest.addr.buf = (UInt8 *) &gSimpleAddr;
  187.         bindRequest.addr.len = k8022BasicAddressLength;     // family type + Ethernet + type field
  188.  
  189.         // Setup bind result
  190.  
  191.         OTMemzero(&bindResult, sizeof(TBind));
  192.         bindResult.addr.buf = (UInt8 *) &resultAddr;
  193.         bindResult.addr.maxlen = sizeof(resultAddr);
  194.  
  195.         // Call bind, which will return the MAC address
  196.         // to which we're bound.
  197.  
  198.         err = OTBind(ep, &bindRequest, &bindResult);
  199.         if (err == noErr) {
  200.             BlockMoveData( resultAddr.fHWAddr, defEnetAddr->bytes, 6);
  201.         }
  202.         
  203.         // Clean up.
  204.         
  205.         junk = OTCloseProvider(ep);
  206.         OTAssert("GetDefaultEthernetAddress: Could not close endpoint", junk == noErr);
  207.     }
  208.     return err;
  209. }
  210.  
  211. static char gHexDigits[16] = "0123456789ABCDEF";
  212.  
  213. static void HexB(UInt8 b, char *buffer)
  214. {
  215.     buffer[0] = gHexDigits[b >> 4];
  216.     buffer[1] = gHexDigits[b & 0x0F];
  217. }
  218.  
  219. static void TrueMain(XCmdPtr xpb)
  220.     // Extra procedure wrapper to avoid horrible register caching problem
  221.     //    whereby the value of result was held in register A3 which was
  222.     //    setup from an A5 relative offset before our A5 had been set up
  223.     //    by InitCodeResource.  Urgh!
  224. {
  225.     OSStatus err;
  226.     EnetAddress defEnetAddr;
  227.     char result[256];
  228.     short i;
  229.  
  230.     err = InitOpenTransport();
  231.     if (err == noErr) {
  232.     
  233.         // Call OT to get the Ethernet address.
  234.         
  235.         err = GetDefaultEthernetAddress(&defEnetAddr);
  236.         
  237.         // Construct a formatted string from the Ethernet address.
  238.         
  239.         if (err == noErr) {
  240.             OTStrCopy(result, "xx:xx:xx:xx:xx:xx");
  241.             for (i = 0; i < 6; i++) {
  242.                 HexB(defEnetAddr.bytes[i], result + (3 * i));
  243.             }
  244.         }
  245.         
  246.         if (err != noErr) {
  247.             OTStrCopy(result, "Error");
  248.         }
  249.         
  250.         // Copy that string out to the returnValue handle.
  251.  
  252.         (void) PtrToHand((Ptr) result, &xpb->returnValue, OTStrLength(result) + 1);
  253.  
  254.         CloseOpenTransport();
  255.     }
  256. }
  257.